package com.v3admin.config;

import cn.dev33.satoken.exception.NotLoginException;
import com.v3admin.common.controller.IResponse;
import com.v3admin.common.exception.BusinessException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * 全局异常处理
 *
 * @author Junpeng.Li
 * @date 2023-12-12 16:10
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * validator 参数检验
     *
     * @param e 异常对象
     * @return 错误消息
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public IResponse handleConstraintViolationException(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        return IResponse.fail(violations.iterator().next().getMessage());
    }

    /**
     * validator 参数检验
     *
     * @param e 异常对象
     * @return 错误消息
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public IResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        return IResponse.fail(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }

    /**
     * 自定义异常 - 业务处理异常
     *
     * @param e 异常对象
     * @return 错误消息
     */
    @ExceptionHandler(BusinessException.class)
    public IResponse handleBusinessException(BusinessException e) {
        return IResponse.fail(e.getCode(), e.getMessage());
    }

    /**
     * sa-token {@link NotLoginException}
     * @param e 异常对象
     * @return 错误消息
     */
    @ExceptionHandler(NotLoginException.class)
    public IResponse handleNotLoginException(NotLoginException e) {
        String type = e.getType();
        switch (type) {
            case "-1":
                return IResponse.fail(401, "未检测到有效的Token信息，请重新登录。");
            case "-2":
                return IResponse.fail(401, "无效的Token信息，请重新登录。");
            case "-3":
                return IResponse.fail(401, "您的登录状态已过期，请重新登录。");
            case "-4":
                return IResponse.fail(401, "您的账号已在其他设备登录，您已被迫下线。请注意：如果这不是您本人的操作，那么您的密码很可能已被泄露，请立刻修改密码。");
            case "-5":
                return IResponse.fail(401, "您的账号已被系统踢下线，请重新登录。");
            case "-6":
                return IResponse.fail(401, "您的账号已被冻结，您已被迫下线。");
            case "-7":
                return IResponse.fail(401, e.getMessage());
            default:
                return IResponse.fail(401, "您还未登录系统，请登录后再操作。");
        }
    }
}
